package main

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"fmt"
	"net/url"
)

// 32字节密钥，AES-256
var key = []byte("12345678901234561234567890123456")

// 16字节初始化向量
var iv = []byte("1234567890123456")

func main() {
	base64EncryptText := aesEncrypt("hello::world")
	fmt.Println("加密后的base64值：", base64EncryptText)
	decryptText := aesDecrypt(base64EncryptText)
	fmt.Println("解密后的值：", decryptText)
	fmt.Println()

	escapeText := url.QueryEscape(base64EncryptText)
	fmt.Println("urlEncode后的值：", escapeText)
	unescapeText, _ := url.QueryUnescape(escapeText)
	fmt.Println("urlDecode后的值：", unescapeText)

}

func aesEncrypt(text string) string {
	// 创建加密块
	block, err := aes.NewCipher(key)
	if err != nil {
		fmt.Println("Error creating cipher block:", err)
		panic(err)
	}

	// 创建一个CBC模式的加密块
	mode := cipher.NewCBCEncrypter(block, iv)

	// 原始数据的字节切片
	textBytes := []byte(text)

	// 对原始数据进行填充
	textBytes = PKCS7Padding(textBytes, aes.BlockSize)

	// 创建一个缓冲区，用于存储加密后的数据
	encryptTextBytes := make([]byte, len(textBytes))

	// 执行加密操作
	mode.CryptBlocks(encryptTextBytes, textBytes)

	// base64编码
	base64EncryptText := base64.StdEncoding.EncodeToString(encryptTextBytes)

	return base64EncryptText
}

func aesDecrypt(base64EncryptText string) string {
	// 创建加密块
	block, err := aes.NewCipher(key)
	if err != nil {
		fmt.Println("Error creating cipher block:", err)
		panic(err)
	}

	// 创建一个CBC模式的解密块
	mode := cipher.NewCBCDecrypter(block, iv)

	encryptTextBytes, err := base64.StdEncoding.DecodeString(base64EncryptText)
	if err != nil {
		fmt.Println("Error base64 decode:", err)
		panic(err)
	}

	// 创建一个缓冲区，用于存储解密后的数据
	textBytes := make([]byte, len(encryptTextBytes))

	// 执行解密操作
	mode.CryptBlocks(textBytes, encryptTextBytes)

	// 去除填充
	textBytes = PKCS7UnPadding(textBytes)

	return string(textBytes)
}

// PKCS7Padding 对数据进行PKCS7填充
func PKCS7Padding(data []byte, blockSize int) []byte {
	padding := blockSize - len(data)%blockSize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(data, padtext...)
}

// PKCS7UnPadding 去除PKCS7填充
func PKCS7UnPadding(data []byte) []byte {
	length := len(data)
	unpadding := int(data[length-1])
	return data[:(length - unpadding)]
}
